﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Utility.Extensions;

namespace Utility.Encrypt
{
    /// <summary>
    /// 对字符串进行加盐 MD5加密
    /// </summary>
    public class StringEncrypt
    {
        static MD5CryptoServiceProvider MD5CSP = new MD5CryptoServiceProvider();
        static Random m_Random = new Random(Guid.NewGuid().GetHashCode());
        const string SALTKEYCHAR = @"1234567890qwertyuiopzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";
        const string CHARACTERS = @"~!@#$%^&*()_+[]\asdfghjkl;:',./{}<>?";
        /// <summary>
        /// 生成指定长度的随机密码
        /// </summary>
        /// <param name="length">生成的密码的字符数,长度必须介于1和128个字符之间.</param>
        /// <param name="numberOfNonAlphanumericCharacters">生成的密码中非字母数字字符的最小数量(如@、#、！、%、&amp; 等)</param>
        /// <returns></returns>
        public static string GetSaltKey(int length = 40, int numberOfNonAlphanumericCharacters = 10)
        {
            if (length == 0 || length > 128)
            {
                length = 40;
            }
            char[] result = new char[length];
            List<int> indexs = new List<int>();
            if (numberOfNonAlphanumericCharacters > length)
            {
                numberOfNonAlphanumericCharacters = length / 2;
            }
            for (int i = 0; i < numberOfNonAlphanumericCharacters; i++)
            {
                var index = m_Random.Next(0, CHARACTERS.Length);
                result[i] = CHARACTERS[index];
                indexs.Add(i);
            }

            for (int i = numberOfNonAlphanumericCharacters; i < length; i++)
            {
                var index = m_Random.Next(0, SALTKEYCHAR.Length);
                result[i] = SALTKEYCHAR[index];
                indexs.Add(i);
            }
            char[] returnChar =new char[length];
            for (int i = 0; i < length; i++)
            {
                var rdValue = m_Random.Next(0, indexs.Count);
                var index = indexs[rdValue];
                returnChar[i] = result[index];
                indexs.RemoveAt(rdValue);
            }
            return new string(returnChar);
        }
        /// <summary>
        /// 对字符串进行加盐MD5加密
        /// </summary>
        /// <param name="str"></param>
        /// <param name="saltKey">盐</param>
        /// <param name="length">生成的密码的字符数,长度必须介于1和128个字符之间.</param>
        /// <param name="numberOfNonAlphanumericCharacters">生成的密码中非字母数字字符的最小数量(如@、#、！、%、&amp; 等)</param>
        /// <returns></returns>
        public static string Encrypt(string str, out string saltKey, int length = 40, int numberOfNonAlphanumericCharacters = 10)
        {
            saltKey = GetSaltKey(length, numberOfNonAlphanumericCharacters);
            return Encrypt(str, saltKey);
        }
        /// <summary>
        ///  对字符串进行加盐MD5加密
        /// </summary>
        /// <param name="str"></param>
        /// <param name="saltKey"></param>
        /// <returns></returns>
        public static string Encrypt(string str, string saltKey)
        {
            byte[] MD5Source = System.Text.Encoding.UTF8.GetBytes(string.Concat(str, saltKey));
            byte[] MD5Out = MD5CSP.ComputeHash(MD5Source);
            return Convert.ToBase64String(MD5Out);
        }
    }
}
